package steed.util;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;

import steed.ext.domain.system.Menu;
import steed.hibernatemaster.Config;
import steed.hibernatemaster.domain.BaseDatabaseDomain;
import steed.hibernatemaster.util.DaoUtil;
import steed.hibernatemaster.util.DaoUtil.ImmediatelyTransactionData;
import steed.hibernatemaster.util.HibernateUtil;
import steed.util.base.BaseUtil;
import steed.util.base.PathUtil;
import steed.util.base.PropertyUtil;
import steed.util.reflect.ReflectUtil;
import steed.util.wechat.MutiAccountSupportUtil;

/**
 * 工具类的工具类
 * @author 战马
 *
 */
public class UtilsUtil {
	private static boolean inited = false;
	
	private static final Map<String, Object> engineMap = new HashMap<>();
	
	/**
	 * 注册引擎
	 *//*
	public static void registEngine(String engineName,Object engine) {
		engineMap.put(engineName, engine);
	}
	public static <T> T getEngine(String engineName) {
		engineMap.put(engineName, engine);
	}
	*/
	
	/**
	 * 初始化所有工具类,使用工具类前请先调用该方法
	 */
	public void initUtils(){
		if (inited) {
			return;
		}
		inited = true;
		/**
		 * 设置log4j日志目录。
		 */
		String logDir = PathUtil.praseRelativePath(PropertyUtil.getConfig("log_dir"));
		System.setProperty("log_dir", logDir);
		System.setProperty("h2DatabasePath", PathUtil.praseRelativePath(PropertyUtil.getConfig("h2DatabasePath")));
		//log4j日志文件编码
		System.setProperty("log_encoding",PropertyUtil.getConfig("characterSet"));
		
		System.setProperty("hibernatesearch.infinispanDataDir", PathUtil.praseRelativePath(PropertyUtil.getConfig("hibernatesearch.infinispanDataDir")));
		
		MutiAccountSupportUtil.setSingleMode(PropertyUtil.getBoolean("wechat.singleMode"));
		
		BaseUtil.getLogger().debug("日志目录--->"+logDir);
		
		configHibernateMaster();
		
		try {
			importInitSqlData();
		} catch (ClassNotFoundException | IOException e) {
			BaseUtil.getLogger().warn("初始数据导入出错!",e);
		}finally {
			DaoUtil.managTransaction();
			DaoUtil.closeSessionNow();
			releaseUtils();
		}
		
//		HibernateUtil.setWhole_closeSession(PropertyUtil.getConstant("whole_closeSession",Boolean.class));
	}

	
	public void importInitSqlData() throws FileNotFoundException, IOException, ClassNotFoundException {
		if (!DaoUtil.isResultNull(new steed.domain.system.Config())) {
			BaseUtil.getLogger().debug("当前数据库已经有数据,不再导入初始数据.");
			return;
		}
		ObjectInputStream objectInputStream = null;
		try {
			objectInputStream = new ObjectInputStream(new FileInputStream(getSqlDataPath()));
			List<BaseDatabaseDomain> list = (List<BaseDatabaseDomain>) objectInputStream.readObject();
			ImmediatelyTransactionData immediatelyTransactionBegin = DaoUtil.immediatelyTransactionBegin();
			for (BaseDatabaseDomain temp:list) {
				temp.save();
			}
			DaoUtil.managTransaction();
			DaoUtil.immediatelyTransactionEnd(immediatelyTransactionBegin);
			
			BaseUtil.getLogger().debug("数据导入成功!");
		}finally {
			if (objectInputStream != null) {
				try {
					objectInputStream.close();
				} catch (IOException e) {
				}
			}
		}
	}
	
	private static String getSqlDataPath() {
		return PathUtil.praseRelativePath("initsqldata.bin");
	}
	
	private void configHibernateMaster() {
		Config.autoBeginTransaction = false;
		Config.autoBeginTransaction = PropertyUtil.getBoolean("dao.autoBeginTransaction");
		Config.isSignalDatabase = PropertyUtil.getBoolean("isSignalDatabase");
		Config.devMode = PropertyUtil.getBoolean("devMode");
		Config.defaultHqlGenerator = ReflectUtil.getInstanceFromProperties("dao.HqlGenerator");
		Config.autoBeginTransaction = false;
		Config.factoryEngine = ReflectUtil.getInstanceFromProperties("dao.factoryEngine");
	}
	
	/**
	 * 释放工具类资源
	 */
	public static void releaseUtils(){
		HibernateUtil.release();
		MutiAccountSupportUtil.relese();
		DaoUtil.relese();
		//TODO ogm与上层工具类解耦
		//OgmUtil.release();
	}
}
